using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.Serialization;

namespace Kontakter
{
    // Only one instance of Options can be created (singleton pattern)
    //
    // Important: if you adding some public property (option), you also
    //            need to modify Assign method by adding here new property
    //            assignment!
    public sealed class Options
    {
        #region Singleton pattern management

        private static Options instance;

        private Options()
        {
        }

        public static Options CreateInstance()
        {
            // "lazy initialization"
            if (instance == null)
            {
                instance = new Options();
            }

            return instance;
        }

        #endregion

        #region Options data

        private string path = System.IO.Path.GetDirectoryName(
            System.Reflection.Assembly.GetExecutingAssembly().Location);

        private const string fileName = "options.xml";

        private string login = "";

        [OptionsInfo("E-mail", "", OptionsGroup.UserInfo)]
        public string Login
        {
            get
            {
                return login;
            }

            set
            {
                login = value;
            }
        }

        private string password = "";

        [OptionsInfo("Password", "", OptionsGroup.UserInfo)]
        public string Password
        {
            get
            {
                return password;
            }

            set
            {
                password = value;
            }
        }

        private WindowState mainWindowState = new WindowState(100, 100, 200, 400);

        [OptionsInfo("", "", OptionsGroup.None)]
        public WindowState MainWindowState
        {
            get
            {
                return mainWindowState;
            }

            set
            {
                mainWindowState = value;
            }
        }

        private string proxyServer = "";

        [OptionsInfo("Proxy server", "", OptionsGroup.Network)]
        public string ProxyServer
        {
            get
            {
                return proxyServer;
            }

            set
            {
                proxyServer = value;
            }
        }

        private int proxyPort = 0;

        [OptionsInfo("Proxy port", "", OptionsGroup.Network)]
        public int ProxyPort
        {
            get
            {
                return proxyPort;
            }

            set
            {
                proxyPort = value;
            }
        }

        private bool useProxyServer = false;

        [OptionsInfo("Use Proxy Server", "", OptionsGroup.Network)]
        public bool UseProxyServer
        {
            get
            {
                return useProxyServer;
            }

            set
            {
                useProxyServer = value;
            }
        }

        private bool proxyRequiresAuthorization = false;

        [OptionsInfo("Proxy Requires Authorization", "", OptionsGroup.Network)]
        public bool ProxyRequiresAuthorization
        {
            get
            {
                return proxyRequiresAuthorization;
            }

            set
            {
                proxyRequiresAuthorization = value;
            }
        }

        private string proxyLogin = "";

        [OptionsInfo("Proxy login", "", OptionsGroup.Network)]
        public string ProxyLogin
        {
            get
            {
                return proxyLogin;
            }

            set
            {
                proxyLogin = value;
            }
        }

        private string proxyPassword = "";

        [OptionsInfo("Proxy Password", "", OptionsGroup.Network)]
        public string ProxyPassword
        {
            get
            {
                return proxyPassword;
            }

            set
            {
                proxyPassword = value;
            }
        }

        private int waitTime = 60;

        [OptionsInfo("Wait Time", "", OptionsGroup.Application)]
        public int WaitTime
        {
            get
            {
                return waitTime;
            }

            set
            {
                waitTime = value;
            }
        }

        #endregion

        #region Save and Load methods

        public void Save()
        {
            XmlSerializer xs = new XmlSerializer(typeof(Options));
            using (FileStream fs = new FileStream(path + "\\" + fileName, FileMode.Create))
                xs.Serialize(fs, instance);
        }

        public bool Load()
        {
            bool result = false;

            if (File.Exists(path + "\\" + fileName))
            {
                Options opts;

                XmlSerializer xs = new XmlSerializer(typeof(Options));
                using (FileStream fs = new FileStream(path + "\\" + fileName, FileMode.Open))
                    opts = (Options)xs.Deserialize(fs);

                instance.Assign(opts);
                result = true;
            }

            return result;
        }

        #endregion

        #region Methods

        // note: bad & ugly!
        public void Assign(Options opts)
        {
            instance.login = opts.login;
            instance.password = opts.password;
            instance.mainWindowState = opts.mainWindowState;
            instance.proxyServer = opts.proxyServer;
            instance.proxyPort = opts.proxyPort;
            instance.useProxyServer = opts.useProxyServer;
            instance.proxyRequiresAuthorization = opts.proxyRequiresAuthorization;
            instance.proxyLogin = opts.proxyLogin;
            instance.proxyPassword = opts.proxyPassword;
            instance.waitTime = opts.waitTime;
        }

        #endregion
    }
}
